home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Misc / msql-1.0.6 / src / msql / msql.c < prev    next >
C/C++ Source or Header  |  1995-05-28  |  8KB  |  483 lines

  1. /*
  2. **    msql.c    - 
  3. **
  4. **
  5. ** Copyright (c) 1993  David J. Hughes
  6. **
  7. ** Permission to use, copy, and distribute for non-commercial purposes,
  8. ** is hereby granted without fee, providing that the above copyright
  9. ** notice appear in all copies and that both the copyright notice and this
  10. ** permission notice appear in supporting documentation.
  11. **
  12. ** This software is provided "as is" without any expressed or implied warranty.
  13. **
  14. ** ID = "$Id:"
  15. **
  16. */
  17.  
  18.  
  19. #ifndef lint
  20. static char RCS_id[] = 
  21.     "msql.c,v 1.3 1994/08/19 08:03:09 bambi Exp";
  22. #endif 
  23.  
  24.  
  25. #include <stdio.h>
  26. #include <sys/types.h>
  27. #include <fcntl.h>
  28.  
  29. #include "common/portability.h"
  30.  
  31. #include "msql.h"
  32.  
  33.  
  34. usage()
  35. {
  36.     (void)fprintf(stderr,"\n\nUsage : msql [-h host] database\n\n");
  37. }
  38.  
  39.  
  40.  
  41. help()
  42. {
  43.     (void)printf("\n\nMiniSQL Help!\n\n");
  44.     (void)printf("The following commands are available :- \n\n");
  45.     (void)printf("\t\\q    Quit\n");
  46.     (void)printf("\t\\g    Go (Send query to database)\n");
  47.     (void)printf("\t\\e    Edit (Edit previous query)\n");
  48.     (void)printf("\t\\p    Print (Print the query buffer)\n");
  49. }
  50.  
  51.  
  52. int max(v1,v2)
  53.     int    v1,
  54.         v2;
  55. {
  56.     if (v1 > v2)
  57.         return(v1);
  58.     else
  59.         return(v2);
  60. }
  61.  
  62.  
  63. bufFill(buf,length,max,filler)
  64.     char    *buf;
  65.     int    length,
  66.         max;
  67.     char    filler;
  68. {
  69.     int    count;
  70.     char    tmpBuf[2];
  71.  
  72.     tmpBuf[0] = filler;
  73.     tmpBuf[1] = 0;
  74.     count = max - length;
  75.     while (count-- >= 0)
  76.     {
  77.         strcat(buf,tmpBuf);
  78.     }
  79. }
  80.  
  81.  
  82.  
  83. fill(length,max,filler)
  84.     int    length,
  85.         max;
  86.     char    filler;
  87. {
  88.     int    count;
  89.  
  90.     count = max - length;
  91.     while (count-- >= 0)
  92.     {
  93.         printf("%c",filler);
  94.     }
  95. }
  96.  
  97.  
  98.  
  99. handleQuery(sock, q)
  100.     int    sock;
  101.     char    *q;
  102. {
  103.     char    *nq,
  104.         sepBuf[5 * 1024];
  105.     int    off,
  106.         length;
  107.     m_result *result;
  108.     m_row    cur;
  109.     m_field    *curField;
  110.  
  111.     if (!q)
  112.     {
  113.         printf("No query specified !!\n");
  114.         return;
  115.     }
  116.     if (!*q)
  117.     {
  118.         printf("No query specified !!\n");
  119.         return;
  120.     }
  121.  
  122.     if (msqlQuery(sock,q) < 0)
  123.     {
  124.         printf("\n\nERROR : %s\n\n",msqlErrMsg);
  125.         return;
  126.     }
  127.     printf("\nQuery OK.\n\n");
  128.  
  129.     result = msqlStoreResult();
  130.     if (!result)
  131.     {
  132.         printf("\n\n");    
  133.         return;
  134.     }
  135.  
  136.     printf("%d rows matched.\n\n",msqlNumRows(result));
  137.  
  138.     /*
  139.     ** Print a pretty header .... 
  140.     */
  141.     (void)bzero(sepBuf,sizeof(sepBuf));
  142.     strcat(sepBuf," +");
  143.     while((curField = msqlFetchField(result)))
  144.     {
  145.         switch(curField->type)
  146.         {
  147.                 case REAL_TYPE:
  148.                 length = strlen(curField->name);
  149.                 if (length < 12)
  150.                 {
  151.                     length = 12;
  152.                 }
  153.                 break;
  154.  
  155.                 case INT_TYPE:
  156.                 length = strlen(curField->name);
  157.                 if (length < 8)
  158.                 {
  159.                     length = 8;
  160.                 }
  161.                 break;
  162.  
  163.                 case CHAR_TYPE:
  164.                 length = max(strlen(curField->name),
  165.                         curField->length);
  166.                 break;
  167.         }
  168.         bufFill(sepBuf,0,length,'-');
  169.         strcat(sepBuf,"-+");
  170.     }
  171.     strcat(sepBuf,"\n");
  172.     printf(sepBuf);
  173.     msqlFieldSeek(result,0);
  174.  
  175.     printf(" |");
  176.     while((curField = msqlFetchField(result)))
  177.     {
  178.         switch(curField->type)
  179.         {
  180.                 case INT_TYPE:
  181.                 length = strlen(curField->name);
  182.                 if (length < 8)
  183.                 {
  184.                     length = 8;
  185.                 }
  186.                 break;
  187.  
  188.                 case REAL_TYPE:
  189.                 length = strlen(curField->name);
  190.                 if (length < 12)
  191.                 {
  192.                     length = 12;
  193.                 }
  194.                 break;
  195.  
  196.                 case CHAR_TYPE:
  197.                 length = max(strlen(curField->name),
  198.                         curField->length);
  199.                 break;
  200.         }
  201.         printf(" %s",curField->name);
  202.         fill(strlen(curField->name),length,' ');
  203.         printf("|");
  204.     }
  205.     printf("\n");
  206.     msqlFieldSeek(result,0);
  207.     printf(sepBuf);
  208.  
  209.  
  210.  
  211.     /*
  212.     ** Print the returned data
  213.     */
  214.     while ((cur = msqlFetchRow(result)))
  215.     {
  216.         off = 0;
  217.         printf(" |");
  218.         while(off < msqlNumFields(result))
  219.         {
  220.             curField = msqlFetchField(result);
  221.             switch(curField->type)
  222.             {
  223.                 case INT_TYPE:
  224.                 length = strlen(curField->name);
  225.                 if (length < 8)
  226.                 {
  227.                     length = 8;
  228.                 }
  229.                 break;
  230.  
  231.                 case REAL_TYPE:
  232.                 length = strlen(curField->name);
  233.                 if (length < 12)
  234.                 {
  235.                     length = 12;
  236.                 }
  237.                 break;
  238.  
  239.                 case CHAR_TYPE:
  240.                 length = max(strlen(curField->name),
  241.                         curField->length);
  242.                 break;
  243.             }
  244.             if (cur[off])
  245.             {
  246.                 printf(" %s",cur[off]);
  247.                 fill(strlen(cur[off]),length,' ');
  248.             }
  249.             else
  250.             {
  251.                 printf(" NULL");
  252.                 fill(4,length,' ');
  253.             }
  254.             printf("|");
  255.             off++;
  256.         }
  257.         printf("\n");
  258.         msqlFieldSeek(result,0);
  259.     }
  260.     printf(sepBuf);
  261.     msqlFreeResult(result);
  262.     printf("\n\n");
  263. }
  264.  
  265.  
  266.  
  267. editQuery(q)
  268.     char    *q;
  269. {
  270.     char    *filename,
  271.         *editor,
  272.         combuf[80];
  273.     int    fd;
  274.  
  275.     filename = tmpnam(NULL);
  276.     fd = open(filename,O_CREAT | O_WRONLY, 0777);
  277.     editor = (char *)getenv("VISUAL");
  278.     if (!editor)
  279.     {
  280.         editor = (char *)getenv("EDITOR");
  281.     }
  282.     if (!editor)
  283.     {
  284.         editor = "vi";
  285.     }
  286.     write(fd,q,strlen(q));
  287.     close(fd);
  288.     sprintf(combuf,"%s %s",editor,filename);
  289.     system(combuf);
  290.     fd = open(filename,O_RDONLY, 0777);
  291.     bzero(q,2048);
  292.     read(fd,q,2048);
  293.     close(fd);
  294.     unlink(filename);
  295. }
  296.     
  297.  
  298.  
  299. main(argc,argv)
  300.     int    argc;
  301.     char    *argv[];
  302. {
  303.     char    qbuf[2048],
  304.         *cp,
  305.         *host = NULL;
  306.     int    newQ = 1,
  307.         prompt = 1,
  308.         sock,
  309.         inString = 0,
  310.         c,
  311.         argsLeft,
  312.         errFlag = 0;
  313.     register u_int inchar;
  314.     extern    int optind;
  315.     extern    char *optarg;
  316.  
  317.         while((c=getopt(argc,argv,"h:"))!= -1)
  318.         {
  319.                 switch(c)
  320.                 {
  321.                         case 'h':
  322.                                 if (host)
  323.                                         errFlag++;
  324.                                 else
  325.                                         host = optarg;
  326.                                 break;
  327.                         case '?':
  328.                                 errFlag++;
  329.                                 break;
  330.                 }
  331.         }
  332.  
  333.         argsLeft = argc - optind;
  334.  
  335.  
  336.     printf("\n");
  337.     if (argsLeft != 1)
  338.     {
  339.         usage();
  340.         exit(1);
  341.     }
  342.  
  343.     /*
  344.     ** If we don't have a hostname have a look at MSQL_HOST
  345.     */
  346.     if (!host)
  347.     {
  348.         host = (char *)getenv("MSQL_HOST");
  349.     }
  350.  
  351.     if ((sock = msqlConnect(host)) < 0)
  352.     {
  353.         printf("ERROR : %s\n",msqlErrMsg);
  354.         exit(1);
  355.     }
  356.  
  357.     if (msqlSelectDB(sock, argv[optind]) < 0)
  358.     {
  359.         printf("ERROR : %s\n",msqlErrMsg);
  360.         exit(1);
  361.     }
  362.  
  363.     /*
  364.     **  Run in interactive mode like the ingres/postgres monitor
  365.     */
  366.  
  367.     printf("Welcome to the miniSQL monitor.  Type \\h for help.\n\n");
  368.     inchar = EOF+1;
  369.     (void)bzero(qbuf,sizeof(qbuf));
  370.     cp = qbuf;
  371.     printf("\nmSQL > ");
  372.     while(!feof(stdin))
  373.     {
  374.         inchar = fgetc(stdin);
  375.         if (inchar == '\\')
  376.         {
  377.             if (inString)
  378.             {
  379.                 *cp++ = inchar;
  380.                 inchar = fgetc(stdin);
  381.                 *cp++ = inchar;
  382.                 continue;
  383.             }
  384.  
  385.             inchar = fgetc(stdin);
  386.             if (inchar == EOF)
  387.                 continue;
  388.             switch(inchar)
  389.             {
  390.                 case 'h':
  391.                     help();
  392.                     newQ = 1;
  393.                     printf("\nmSQL > ");
  394.                     prompt=0;
  395.                     break;
  396.                 case 'g':
  397.                     handleQuery(sock,qbuf);
  398.                     newQ = 1;
  399.                     inString = 0;
  400.                     printf("\nmSQL > ");
  401.                     prompt=0;
  402.                     break;
  403.                 case 'e':
  404.                     editQuery(qbuf);
  405.                     printf("Query buffer\n");
  406.                     printf("------------\n");
  407.                     printf("%s\n[continue]\n",qbuf);
  408.                     printf("    -> ");
  409.                     prompt=0;
  410.                     cp = qbuf + strlen(qbuf);
  411.                     break;
  412.                 case 'q':
  413.                     msqlClose(sock);
  414.                     printf("\n\nBye!\n\n");    
  415.                     exit(0);
  416.  
  417.                 case 'p':
  418.                     printf("\nQuery buffer\n");
  419.                     printf("------------\n");
  420.                     printf("%s\n[continue]\n",qbuf);
  421.                     printf("    -> ");
  422.                     prompt=0;
  423.                     break;
  424.                 default:
  425.                     printf("\n\nUnknown command.\n\n");
  426.                     newQ = 1;
  427.                     printf("\nmSQL > ");
  428.                     prompt=0;
  429.                     break;
  430.             }
  431.         }
  432.         else
  433.         {
  434.             if (inchar == '\'')
  435.             {
  436.                 if (inString)
  437.                     inString = 0;
  438.                 else
  439.                     inString = 1;
  440.             }
  441.             if (inString)
  442.             {
  443.                 *cp++ = inchar;
  444.                 continue;
  445.             }
  446.             if ((newQ )&& (inchar != '\n'))
  447.             {
  448.                 newQ = 0;
  449.                 cp = qbuf;
  450.                 (void)bzero(qbuf,sizeof(qbuf));
  451.             }
  452.             if (inchar == '#')
  453.             {
  454.                 while(!feof(stdin))
  455.                 {
  456.                     inchar = fgetc(stdin);
  457.                     if (inchar == '\n')
  458.                     {
  459.                         break;
  460.                     }
  461.                 }
  462.                 continue;
  463.             }
  464.             if (inchar == '\n')
  465.             {
  466.                 if (prompt)
  467.                 {
  468.                     printf("    -> ");
  469.                 }
  470.                 else
  471.                 {
  472.                     prompt++;
  473.                     continue;
  474.                 }
  475.             }
  476.             *cp++ = inchar;
  477.         }
  478.     }
  479.     msqlClose(sock);
  480.     printf("\nBye!\n\n");
  481.     exit(0);
  482. }
  483.